#include "client_main.h"
#include "ui_client_main.h"


Client_Main::Client_Main(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Client_Main)
{
    ui->setupUi(this);
    this->setWindowIcon(QIcon(":/new/prefix1/w4.png"));
    this->setWindowTitle("用户登陆");
    ui->passwdLineEdit->setEchoMode(QLineEdit::Password);
    ui->userNameLineEdit->setMaxLength(NAME_PASSWORD_LEN);
    ui->userNameLineEdit->setClearButtonEnabled(true);
    ui->passwdLineEdit->setMaxLength(NAME_PASSWORD_LEN);
    ui->passwdLineEdit->setClearButtonEnabled(true);

    //创建线程，用于TCP通信
    QThread *userThread = new QThread(this);
    user_TCP = new TCP_Thread;
    user_TCP->moveToThread(userThread);
    userThread->start();

    //进行TCP连接
    connect(this,&Client_Main::s_connectSockfd,user_TCP,&TCP_Thread::ConnectToServer);
    emit s_connectSockfd(QString(SERVER_MASTER_IP),qint16(SERVER_USER_PORT));

    //创建设备界面，登陆成功后进入
    device_Console = new Device_Console;

    //接收Device_Console退出登陆信号
    connect(device_Console,&Device_Console::s_Logout,this,&Client_Main::ConsoleLogout);

    //向TCP线程发送数据包，并使其发送至服务器
    connect(this,&Client_Main::s_sendMsg,user_TCP,&TCP_Thread::SendMsg);

    //接收TCP线程返回的数据包
    connect(user_TCP,&TCP_Thread::s_recvMsg,this,&Client_Main::RecvUserMsg);

    //接受线程返回错误
    connect(user_TCP,&TCP_Thread::s_wrongMsg,this,&Client_Main::WrongBox);

    //关闭线程TCP
    connect(this,&Client_Main::s_closeSockfd,user_TCP,&TCP_Thread::CloseTCP);
    connect(device_Console,&Device_Console::s_closeSockfd,user_TCP,&TCP_Thread::CloseTCP);

    //结束线程
    connect(this,&Client_Main::destroyed,this,[=](){
        userThread->quit();
        userThread->wait();
        MYLOG << "userThread线程：结束完毕";
        delete userThread;
    });
}

Client_Main::~Client_Main()
{
    delete user_TCP;
    delete device_Console;
    delete ui;
}

//错误提示窗口
void Client_Main::WrongBox(QString title,QString word)
{
    QMessageBox::warning(this,title,word);
}

//进入二级界面
void Client_Main::LoginConsole()
{
    device_Console->DoInit(g_cUserName);
    this->hide();
    device_Console->show();
}

//接收数据包
void Client_Main::RecvUserMsg(QVariant v_msg)
{
    MsgStruct recvMsg = v_msg.value<MsgStruct>();
    //确定包类型
    switch (recvMsg.data_type)
    {
        case MSG_DATA_ACCOUNT_LOGIN:
            TakeLoginMsg(recvMsg);
            break;
        case MSG_DATA_ACCOUNT_REGISTER:
            TakeRegisterMsg(recvMsg);
            break;
        default:
            WrongBox(QString("Msg failed"),QString("data_type error:%1").arg(recvMsg.data_type));
            break;
    }
}

//登陆槽函数
void Client_Main::on_logInPushButton_clicked()
{

    MsgStruct sendMsg;
    char name[NAME_PASSWORD_LEN] = {0};
    char password[NAME_PASSWORD_LEN] = {0};
    QByteArray sendData,nameData,passwdData,recvData;
    memset(&sendMsg,0X0,sizeof (MsgStruct));
    //写入信息
    nameData = ui->userNameLineEdit->text().toLatin1();
    passwdData = ui->passwdLineEdit->text().toLatin1();
    strcpy(name,nameData.data());
    strcpy(password,passwdData.data());
    sendMsg.version = MSG_VERSION;
    sendMsg.header_len = MSG_HEADER_STABLE_LEN;
    sendMsg.encrypt_type = MSG_ENCRYPT_NONE;
    sendMsg.protocol_type = MSG_PROTOCOL_C2S;
    sendMsg.data_type = MSG_DATA_ACCOUNT_LOGIN;
    sendMsg.seq_num = -1;
    sendMsg.frag_flag = MSG_FLAG_FRAG_NO;
    sendMsg.frag_offset = 0;
    sendMsg.custom1 = ui->userNameLineEdit->text().length();
    sendMsg.custom2 = ui->passwdLineEdit->text().length();
    sendMsg.total_len = MSG_HEADER_STABLE_LEN+sendMsg.custom1+sendMsg.custom2;
    sendMsg.source_addr = 0x7F000001;
    sendMsg.target_addr = 0x7F000001;
    memcpy(sendMsg.data, name, sendMsg.custom1);
    strcpy(g_cUserName, name);//保存用户名，登陆成功后给到下一级界面
    memcpy(sendMsg.data + 1 + sendMsg.custom1, password, sendMsg.custom2);
    //给TCP线程发送包
    QVariant emitToChildMsg;
    emitToChildMsg.setValue(sendMsg);
    emit s_sendMsg(emitToChildMsg);
}

//接收登陆结果
void Client_Main::TakeLoginMsg(MsgStruct recvMsg)
{
    if(recvMsg.custom1 == MSG_CUSTOM1_ACCOUNT_LOGIN_SUCCESS)
    {
        MYLOG << "Login successfully!";
        LoginConsole();
        return;
    }
    else if(recvMsg.custom1 == MSG_CUSTOM1_ACCOUNT_LOGIN_FAILURE)
    {
        switch (recvMsg.custom2)
        {
            case MSG_CUSTOM2_ACCOUNT_LOGIN_FAILURE_ACCOUNT:
                WrongBox(QString("Login failed"),QString("Wrong account or account not registered"));
                break;
            case MSG_CUSTOM2_ACCOUNT_LOGIN_FAILURE_PASSWORD:
                WrongBox(QString("Login failed"),QString("Wrong password"));
                break;
            case MSG_CUSTOM2_ACCOUNT_LOGIN_FAILURE_CONNECT:
                WrongBox(QString("Login failed"),QString("Abnormal connection"));
                break;
            case MSG_CUSTOM2_ACCOUNT_LOGIN_FAILURE_DATABASE:
                WrongBox(QString("Login failed"),QString("Database exception"));
                break;
            default:
                WrongBox(QString("Login failed"),QString("unknow reason"));
                break;
        }
    }
    else
    {
        WrongBox(QString("Login failed"),QString("Return unknow status:%1").arg(recvMsg.custom1));
    }
}

//注册槽函数
void Client_Main::on_registerPushButton_clicked()
{
    MsgStruct sendMsg;
    char name[NAME_PASSWORD_LEN] = {0};
    char password[NAME_PASSWORD_LEN] = {0};
    QByteArray nameData,passwdData;
    memset(&sendMsg,0X0,sizeof (MsgStruct));
    //写入信息
    nameData = ui->userNameLineEdit->text().toLatin1();
    passwdData = ui->passwdLineEdit->text().toLatin1();
    strcpy(name,nameData.data());
    strcpy(password,passwdData.data());
    sendMsg.version = MSG_VERSION;
    sendMsg.header_len = MSG_HEADER_STABLE_LEN;
    sendMsg.encrypt_type = MSG_ENCRYPT_NONE;
    sendMsg.protocol_type = MSG_PROTOCOL_C2S;
    sendMsg.data_type = MSG_DATA_ACCOUNT_REGISTER;
    sendMsg.seq_num = -1;
    sendMsg.frag_flag = MSG_FLAG_FRAG_NO;
    sendMsg.frag_offset = 0;
    sendMsg.custom1 = ui->userNameLineEdit->text().length();
    sendMsg.custom2 = ui->passwdLineEdit->text().length();
    sendMsg.total_len = MSG_HEADER_STABLE_LEN+sendMsg.custom1+sendMsg.custom2;
    sendMsg.source_addr = 0x7F000001;
    sendMsg.target_addr = 0x7F000001;
    memcpy(sendMsg.data, name, sendMsg.custom1);
    memcpy(sendMsg.data + 1 + sendMsg.custom1, password, sendMsg.custom2);
    //给TCP线程发送包
    QVariant emitToChildMsg;
    emitToChildMsg.setValue(sendMsg);
    emit s_sendMsg(emitToChildMsg);
}

//注销槽函数
void Client_Main::ConsoleLogout()
{
    ui->passwdLineEdit->setText("");
    emit s_closeSockfd();

    while(1)
    {
        if(!user_TCP->g_bTcpStateFlag){
            emit s_connectSockfd(QString(SERVER_MASTER_IP),qint16(SERVER_USER_PORT));
            break;
        }
    }

    this->show();

}

//接收注册结果
void Client_Main::TakeRegisterMsg(MsgStruct recvMsg)
{
    if(recvMsg.custom1 == MSG_CUSTOM1_ACCOUNT_REG_SUCCESS)
        {
            WrongBox(QString("success"),QString("Congratulations！You registered successfully!"));
        }
        else if(recvMsg.custom1 == MSG_CUSTOM1_ACCOUNT_REG_FAILURE)
        {
            switch (recvMsg.custom2)
            {
                case MSG_CUSTOM2_ACCOUNT_REG_FAILURE_ALREADY:
                    WrongBox(QString("failed"),QString("Account already exist"));
                    break;
                case MSG_CUSTOM2_ACCOUNT_REG_FAILURE_CONNECT:
                    WrongBox(QString("failed"),QString("Connection failed"));
                    break;
                case MSG_CUSTOM2_ACCOUNT_REG_FAILURE_DATABASE:
                    WrongBox(QString("failed"),QString("Database error"));
                    break;
                default:
                    WrongBox(QString("failed"),QString("unknow reason"));
                    break;
            }
        }
        else
        {
            WrongBox(QString("failed"),QString("unknow reason:%1").arg(recvMsg.custom1));
        }
}

//用户名输入正则表达式判断
void Client_Main::on_userNameLineEdit_textChanged(const QString &arg1)
{
    QRegExp rx(QString("^[A-Za-z0-9]+$"));
    if(rx.exactMatch(arg1))
    {
        ui->userNameLineEdit->setStyleSheet("border:1px solid rgb(0, 0, 0);");
    }
    else
    {
        ui->userNameLineEdit->setStyleSheet("border:1px solid rgb(255, 0, 0);");
        ui->userNameLineEdit->setToolTip(QString("Tips: alphabet, number, underscore"));
    }
}

//密码输入正则表达式判断
void Client_Main::on_passwdLineEdit_textChanged(const QString &arg1)
{
    QRegExp rx(QString("^[A-Za-z0-9]+$"));
    if(rx.exactMatch(arg1))
    {
        ui->passwdLineEdit->setStyleSheet("border:1px solid rgb(0, 0, 0);");
    }
    else
    {
        ui->passwdLineEdit->setStyleSheet("border:1px solid rgb(255, 0, 0);");
        ui->passwdLineEdit->setToolTip(QString("Tips: alphabet, number, underscore"));
    }
}

//重写关闭事件，以发送信号结束线程内TCP
void Client_Main::closeEvent(QCloseEvent *event)
{
    emit s_closeSockfd();
    while(1)
    {
        if(!user_TCP->g_bTcpStateFlag)
        {
            break;
        }
    }

    if(event){};//消除未使用警告
}
